
package com.x52im.rbchat.logic.chat_friend.vv;

import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;

import com.eva.android.DelayedHandler;
import com.eva.android.NewAsyncTask;
import com.eva.android.widget.WidgetUtils;
import com.eva.android.widget.WidgetUtils.ToastType;
import com.x52im.rbchat.Const;
import com.x52im.rbchat.MyApplication;
import com.x52im.rbchat.R;
import com.x52im.rbchat.cache.ImageCacheLoader;
import com.x52im.rainbowchat.http.logic.dto.RosterElementEntity;
import com.x52im.rbchat.logic.chat_friend.utils.MessageHelper;
import com.x52im.rbchat.logic.chat_friend.utils.RealTimeVoiceMessageHelper;
import com.x52im.rbchat.logic.chat_root.model.VoipRecordMeta;
import com.x52im.rbchat.utils.PromtHelper;
import com.x52im.rbchat.network.im.ChatMessageEventListener;
import com.x52im.rbchat.permission2.PermissionManager;

import java.text.MessageFormat;
import java.util.List;
import java.util.Observer;

import androidx.appcompat.app.AppCompatDialog;

/**
 * 用户处理好友发送过来的实时语音聊天权限对话框.
 * <p>
 * 本类中用于处理语音聊天时的请求控制权限的交互.
 * 
 * @author Jack Jiang(http://www.52im.net/space-uid-1.html)
 * @version 1.0
 */
public class VoiceCallComeDialog extends AppCompatDialog//Dialog
{
	private final static String TAG = VoiceCallComeDialog.class.getSimpleName();
	
	private Activity parentActivity = null;
	private String parentFriendUID = null;
	
	private TextView viewNickName = null;
	private ViewGroup btnReject = null;
	private ViewGroup btnAccept = null;
	/** 好友头像 */
	private ImageView viewAvatar = null;
	
	private MediaPlayer promtMp = null;
	
	/** true表示本界面正在运行（即实时语音正在被呼叫）中 */
	private static boolean beCalling = false;
	
	/** 
	 * 音视频聊天呼入事件观察者（本观察者将在{@link ChatMessageEventListener}收到对
	 * 方（视频聊天接收方）的“取消视频聊天请求”的处理时被通知）.
	 */
	private Observer realTimeVoiceCallComeObserver = (observable, data) -> {
		showHint(parentActivity.getString(R.string.real_time_chat_be_request_cancel));
		VoiceCallComeDialog.this.dismiss();
	};
	
	// 超时处理Handler
	private DelayedHandler delayedHandler = new DelayedHandler(VoiceCallOutDialog.DEFAULT_CALLING_TIMEOUT){
		@Override
		protected void fireRun() {
			WidgetUtils.showToastLong(parentActivity, parentActivity.getString(R.string.real_time_chat_be_request_timeout), ToastType.WARN);
			VoiceCallComeDialog.this.dismiss();
		}
	};
	
	public VoiceCallComeDialog(Activity parentActivity, String parentFriendUID) 
	{
		super(parentActivity, R.style.voice_call_dialog);//R.style.MyDialog);
		this.parentActivity = parentActivity;
		this.parentFriendUID = parentFriendUID;
	}
	public VoiceCallComeDialog(Activity parentActivity, int theme, String parentFriendUID)
	{
		super(parentActivity, theme);
		this.parentActivity = parentActivity;
		this.parentFriendUID = parentFriendUID;
	}

	@Override
	public void show()
	{
		super.show();

		// 收到语音聊天后，首先进行相关权限的检查，并决定是否继续
		permissionCheck();
	}

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

		beCalling = true;
		// 初始化
		init();

//		// 设置 dialog 背景全透明（参考资料：https://www.jianshu.com/p/d419ef83bf70）
//		Window window = this.getWindow();
//		if (window != null) {
//			// 去除系统自带的margin
//			window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
//			// 设置dialog在界面中的属性
//			window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
//			// 背景全透明
//			window.setDimAmount(0f);
//
//
//
////			window.setNavigationBarColor(parentActivity.getResources().getColor(R.color.white));//导航栏颜色，不写默认黑色
//////			window.na(true); //导航栏图标是深色，不写默认为亮色
//		}

		// 以下代码用于解决底部导航栏是黑色的问题（资料：http://www.yiidian.com/questions/260426）
		try{
			getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
		} catch (Exception e) {
			Log.w(TAG, e);
		}

//		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
//			setWhiteNavigationBar(this);
//		}

		_onResume();
	}

//	@RequiresApi(api = Build.VERSION_CODES.M)
//	private void setWhiteNavigationBar(@NonNull Dialog dialog) {
//		Window window = dialog.getWindow();
//		if (window != null) {
//			DisplayMetrics metrics = new DisplayMetrics();
//			window.getWindowManager().getDefaultDisplay().getMetrics(metrics);
//
//			GradientDrawable dimDrawable = new GradientDrawable();
//
//			GradientDrawable navigationBarDrawable = new GradientDrawable();
//			navigationBarDrawable.setShape(GradientDrawable.RECTANGLE);
//			navigationBarDrawable.setColor(Color.WHITE);
//
//			Drawable[] layers = {dimDrawable, navigationBarDrawable};
//
//			LayerDrawable windowBackground = new LayerDrawable(layers);
//			windowBackground.setLayerInsetTop(1, metrics.heightPixels);
//
//			window.setBackgroundDrawable(windowBackground);
//		}
//	}
	
	protected void _onResume()
	{
		MyApplication.getInstance(parentActivity).getIMClientManager().getTransDataListener().setRealTimeVoiceCallComeObserver(realTimeVoiceCallComeObserver);
	}
	protected void _onPause()
	{
		MyApplication.getInstance(parentActivity).getIMClientManager().getTransDataListener().setRealTimeVoiceCallComeObserver(null);
	}
	
	public void dismissNotSendReject()
	{
		_onPause();
		_finish(true);
		super.dismiss();
	}
	@Override
	public void dismiss()
	{
		_onPause();
		_finish(false);
		super.dismiss();
	}
	
	/**
	 * @param finishNotSendReject 当正常进入到音视频界面时，就不需要发送这个拒绝命令了，本界面中其它场合下
	 * 发送的拒绝命令相当于“结束”（比如程序崩溃这样的非正常退出行为时）。
	 */
	public void _finish(boolean finishNotSendReject)
	{
		if(delayedHandler != null)
		{
			delayedHandler.stop();
			delayedHandler = null;
		}

        try
        {
            if(promtMp != null)
                promtMp.stop();
        }
        catch (Exception e)
        {
            Log.w(TAG, e);
        }
		
		if(!finishNotSendReject)
			fireReject();
		
		System.out.println("DDDDDDDDDDDD_finish时finishNotSendReject？"+finishNotSendReject);
//		super.finish();

		beCalling = false;
	}
	
	private void init()
	{
		initViews();
		initListeners();
	}
	
	private void initViews()
	{
		this.setContentView(R.layout.voice_call_come_dialog);
		this.setCanceledOnTouchOutside(false);
		
		viewNickName = this.findViewById(R.id.chatting_real_time_voice_request_come_dialog_nickNameView);
		btnReject = this.findViewById(R.id.chatting_real_time_voice_request_come_dialog_rejectBtn);
		btnAccept = this.findViewById(R.id.chatting_real_time_voice_request_come_dialog_acceptBtn);
		viewAvatar = this.findViewById(R.id.chatting_real_time_voice_request_come_dialog_target_avatarView);

		//** 对方的好友信息
		RosterElementEntity friendInfo = MyApplication.getInstance2().getIMClientManager().getFriendsListProvider().getFriendInfoByUid2(parentFriendUID);
		// ** 显示头像和昵称
		if(friendInfo != null) {
			ImageCacheLoader.loadAvatarImgWithGlide(parentActivity, friendInfo.getUser_uid(), friendInfo.getUserAvatarFileName(), viewAvatar
					, 50, R.drawable.default_avatar_yuan_100_3x, true, false);
			viewNickName.setText(friendInfo.getNickname());//30
		}
		
		//** 
//		showHint($$(R.string.video_call_come_invite_to));
		promtMp = PromtHelper.calling2Promt(parentActivity, parentFriendUID);
	}

	private void initListeners()
	{
		// 拒绝
		btnReject.setOnClickListener(v -> {
			operationImpl(false);
			fireRejectExtra();

			// 发出一条音视频聊天记录（这样的话，本地和远端都会有记录的哟）
			MessageHelper.sendVoipRecordMessageAsync(
					// context用全局Application对象，确保消息的发送不依赖于本Activity的生命周期
					MyApplication.getInstance2()
					, parentFriendUID
					, new VoipRecordMeta(VoipRecordMeta.VOIP_TYPE_VOICE, VoipRecordMeta.RECORD_TYPE_REQUEST_REJECT)
					, null);
		});
		// 同意
		btnAccept.setOnClickListener(v -> {
			if(Const.NO_REAL_TIME_VOICE$VEDIO_SERVICE) {
				WidgetUtils.showToastLong(parentActivity, "因测试条件有限，目前实时音视频服务尚未部署，与此相关的功能可能无法正确响应，请原谅！", ToastType.WARN);
			}

			operationImpl(true);
			fireAcceptExtra();
		});
	}
	
	public void showHint(String text)
	{
		// 播放提示音
		PromtHelper.playendPromt(parentActivity);
		WidgetUtils.showToast(parentActivity, text, ToastType.INFO);
	}
	
	private void fireReject()
	{
		// 新聊天框架中的网络数据发送需要放到异步线程里（Android2.3以上版本要求网络交互不允许发生在主线程里）
		new NewAsyncTask<Object, Integer, Integer>(){
			@Override
			protected Integer doInBackground(Object... params)
			{
				RosterElementEntity friendERR = MyApplication.getInstance(parentActivity)
						.getIMClientManager().getFriendsListProvider().getFriendInfoByUid2(parentFriendUID);
				int code = RealTimeVoiceMessageHelper.sendVideoAndVoiceRequest$Reject_to$a(parentActivity
						, friendERR.getUser_uid()
						, MyApplication.getInstance(parentActivity).getIMClientManager().getLocalUserInfo().getUser_uid()
						, false, -1);
				return code;
			}

			@Override
			protected void onPostExecute(Integer code)
			{
				if(code == 0)
				{
					showHint(parentActivity.getString(R.string.real_time_chat_be_request_abort));
//					startActivity(IntentFactory.createVideoChatIntent(VideoCallComeActivity.this
//							, friendERR.getUser_id(), friendUIDForInit));
				}
				else
				{
					showHint(parentActivity.getString(R.string.real_time_chat_be_request_abort_faild));
				}
			}
		}.execute();
	}
	
	/**
	 * 拒绝对方的请求后要做的事。子类可重写本方法实现ui的展现.
	 */
	protected void fireRejectExtra()
	{
		// 默认什么也不做
	}
	
	/**
	 * 同意对方的请求但发送同意消息回给对方前要做的事。子类可重写本方法实现ui的展现.
	 */
	protected void fireAcceptPreExtra()
	{
		// 默认什么也不做
	}
	/**
	 * 同意对方的请求后要做的事。子类可重写本方法实现ui的展现.
	 */
	protected void fireAcceptExtra()
	{
		// 默认什么也不做
	}
	/**
	 * 同意对方的请求后但把同意消息发回给对方时出错时要做的事。子类可重写本方法实现ui的展现.
	 */
	protected void fireAcceptAndSendMesageButErrorExtra()
	{
		// 默认什么也不做
	}
	
	/**
	 * 操作实施方法.
	 * 
	 * @param accept true表示接受控制，false表示拒绝
	 */
	private void operationImpl(boolean accept)
	{
		RosterElementEntity ree = MyApplication.getInstance(parentActivity).getIMClientManager().getFriendsListProvider().getFriendInfoByUid2(parentFriendUID);
		final String descStr = accept ? "[Accepted.]" : "[Refused.]";
		
		if(ree.isOnline())
		{
			if(accept)
			{
				// 新聊天框架中的网络数据发送需要放到异步线程里（Android2.3以上版本要求网络交互不允许发生在主线程里）
				new NewAsyncTask<Object, Integer, Integer>(){
					@Override
					protected void onPreExecute() 
					{
                        try
                        {
                            if(promtMp != null)
                                promtMp.stop();
                        }
                        catch (Exception e)
                        {
                            Log.w(TAG, e);
                        }
				    }
					
					@Override
					protected Integer doInBackground(Object... params)
					{
						RosterElementEntity friendERR = MyApplication.getInstance(parentActivity)
								.getIMClientManager().getFriendsListProvider().getFriendInfoByUid(parentFriendUID);
						
						//
						fireAcceptPreExtra();
						
						//** 12-31日后【实时音频】“同意”指令的发出和接收方案2之【第1/2步：什么也不作，同意指令已经在fireAcceptPreExtra方法中requestAction了】
						int code = 0;
						
						//** 12-31日前【实时音频】“同意”指令的发出和接收方案1之【第1/2步：发送同意指令】
//						int code = RealTimeVoiceMessageHelper.sendVideoAndVoiceRequest$Accept_to$a(parentActivity
//								, friendERR.getUser_id()
//								, MyApplication.getInstance(parentActivity).getLocalUserInfoProvider().getUser_uid()
//								, false, -1);
						
						return code;
					}

					@Override
					protected void onPostExecute(Integer code)
					{
						if(code == 0)
						{
							Log.d(TAG, descStr);
							
							// ** 注意：这里是正常同意
//							_onPause();
//							_finish(true); // 此时就不需要发送“拒绝”命令了，因为这个界面是正常进入音视频界面哦
//							preDismiss();  // 此时就不需要发送“拒绝”命令了，因为这个界面是正常进入音视频界面哦
//							VoiceCallComeDialog.super.dismiss(); // 注意这里调用的是super哦
							dismissNotSendReject();
						}
						else
						{
							showHint(parentActivity.getString(R.string.real_time_chat_be_request_agree_faild));
//							WidgetUtils.showToast(VideoCallComeActivity.this
//									, "聊天请求没有成功发出，请稍后重试."
//									, ToastType.WARN);
//							finish();
							
							dismissNotSendReject();
							fireAcceptAndSendMesageButErrorExtra();
						}
					}
				}.execute();
			}
			// reject
			else
			{
				VoiceCallComeDialog.this.dismiss();
			}
		}
		else
		{
			WidgetUtils.showToast(parentActivity
					, String.valueOf(viewNickName.getText())+" is offline."
					, ToastType.INFO);
		}
	}
	
	public static boolean isBeCalling()
	{
		return beCalling;
	}

	/**
	 * 收到视频聊天后，首先进行相关权限的检查，并决定是否继续。
	 *
	 * 说明：动态权限申请用于targetSDKVersion>=23，即Android6.0及以上系统时。
	 */
	private void permissionCheck()
	{
		Observer obsOnDenied = (o, permissionNamesObj) -> {
			final List<String> permissionNames = (List<String>)permissionNamesObj;
			String message = MessageFormat.format(parentActivity.getResources().getString(R.string.rb_permission_fail_to_cancel), permissionNames);
			Log.w(TAG, "[动态权限onDenied]"+message);
			WidgetUtils.showToastLong(parentActivity, message, ToastType.WARN);

			// 如果用户拒绝了权限申请，则关闭当前界面（并发出拒绝处理结果）
			btnReject.performClick();
		};

		// 开始动态权限申请（用于targetSDKVersion>=23，即Android6.0及以上系统时）
		PermissionManager.requestPermission_CAMERA_$_RECORD_AUDIO(parentActivity
				// 权限获取成功或已经取得此权限时
				, (o, arg) -> { }//** 权限正常获取，什么也不需要做，等用户自已决定
				, obsOnDenied);
	}
}
